//
//  HHPlayerNoControlView.m
//  HHAVPlayer
//
//  Created by lch on 2022/1/21.
//

#import "HHPlayerNoControlView.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import <Masonry/Masonry.h>
#import <HHBlockKit/HHBlockHeader.h>
#import "HHLuminanceView.h"

@interface HHPlayerNoControlView ()


/** 播放属性 */
@property (nonatomic, strong) AVPlayer            *player;
/** 播放属性 */
@property (nonatomic, strong) AVPlayerItem        *playerItem;
/** playerLayer */
@property (nonatomic, strong) AVPlayerLayer       *playerLayer;
/** 定义一个实例变量，保存枚举值 */
@property (nonatomic, assign) PanDirection        panDirection;
/** 播发器的几种状态 */
@property (nonatomic, assign) HHPlayerState       state;
/** 是否为全屏 */
@property (nonatomic, assign) BOOL                isFullScreen;
/** 是否在调节音量*/
@property (nonatomic, assign) BOOL                isVolume;
/** 是否被用户暂停 */
@property (nonatomic, assign) BOOL                isPauseByUser;
/** 是否播放本地文件 */
@property (nonatomic, assign) BOOL                isLocalVideo;
/** 是否再次设置URL播放视频 */
@property (nonatomic, assign) BOOL                repeatToPlay;
/** 播放完了*/
@property (nonatomic, assign) BOOL                playDidEnd;
/** 进入后台*/
@property (nonatomic, assign) BOOL                didEnterBackground;
/** 播放/暂停按钮*/
@property (nonatomic, strong) UIButton            *playerStateBut;

@end

@implementation HHPlayerNoControlView
#pragma mark - 单例
+ (instancetype)sharedPlayerView
{
    static HHPlayerNoControlView *playerView = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        playerView = [[HHPlayerNoControlView alloc] init];
    });
    return playerView;
}
- (instancetype)init{
    if (self = [super init]) {
        self.isRepeatPlay = NO;
       
    }
    return self;
}
#pragma mark - videoURL的setter方法
- (void)setVideoURL:(NSURL *)videoURL
{
    // 如果已经下载过这个video了，那么直接播放本地视频
    if ([[HHDownloadManager sharedInstance] isCompletion:videoURL.absoluteString]) {
        videoURL = [NSURL fileURLWithPath:HHFileFullpath(videoURL.absoluteString)];
    }
    _videoURL = videoURL;
    
    // 播放开始之前（加载中）设置站位图
    UIImage *image = HHPlayerImageName(@"loading_bgView");
    self.layer.contents = (id) image.CGImage;
    
    // 每次加载视频URL都设置重播为NO
    self.repeatToPlay = NO;
    self.playDidEnd   = NO;
    
    // 添加通知
    // app退到后台
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground) name:UIApplicationWillResignActiveNotification object:nil];
    // app进入前台
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterPlayGround) name:UIApplicationDidBecomeActiveNotification object:nil];
    // 设置Player相关参数
    [self configHHPlayer];
}
#pragma mark - 设置Player相关参数
- (void)configHHPlayer
{
    // 初始化playerItem
    self.playerItem  = [AVPlayerItem playerItemWithURL:self.videoURL];

    // 每次都重新创建Player，替换replaceCurrentItemWithPlayerItem:，该方法阻塞线程
    self.player = [AVPlayer playerWithPlayerItem:self.playerItem];

    // 初始化playerLayer
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];

    // 此处为默认视频填充模式
    self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
    // 添加playerLayer到self.layer
    [self.layer insertSublayer:self.playerLayer atIndex:0];

    // 添加手势
    // 双击(播放/暂停)
    UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(doubleTapAction:)];
    [doubleTap setNumberOfTapsRequired:2];
    [self addGestureRecognizer:doubleTap];

    // 本地文件不设置HHPlayerStateBuffering状态
    if ([self.videoURL.scheme isEqualToString:@"file"]) {
        self.state = HHPlayerStatePlaying;
        self.isLocalVideo = YES;
    } else {
        self.state = HHPlayerStateBuffering;
        self.isLocalVideo = NO;
    }
    // 开始播放
    [self play];
    // 是否被用户暂停
    self.isPauseByUser = NO;

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];
    
    // 强制让系统调用layoutSubviews 两个方法必须同时写
    [self setNeedsLayout]; //是标记 异步刷新 会调但是慢
    [self layoutIfNeeded]; //加上此代码立刻刷新
    
    
}

#pragma mark - layoutSubviews
- (void)layoutSubviews
{
    [super layoutSubviews];
    self.playerLayer.frame = self.bounds;

    [UIApplication sharedApplication].statusBarHidden = NO;
  
    // 4s，屏幕宽高比不是16：9的问题,player加到控制器上时候
    if (iPhone4s) {
        [self mas_updateConstraints:^(MASConstraintMaker *make) {
            make.height.mas_offset(SCREENWIDTH*2/3);
        }];
    }
    // fix iOS7 crash bug
    [self layoutIfNeeded];
}


#pragma mark - 双击播放/暂停
- (void)doubleTapAction:(UITapGestureRecognizer *)gesture
{
    self.isPauseByUser = !self.isPauseByUser;
    if (self.isPauseByUser) {
        [self play];
        self.playerStateBut.hidden = YES;
        if (self.state == HHPlayerStatePause) {
            self.state = HHPlayerStatePlaying;
        }
    } else {
        [self pause];
        self.playerStateBut.hidden = NO;
        if (self.state == HHPlayerStatePlaying) {
            self.state = HHPlayerStatePause;
        }
    }
}
#pragma mark - 播放
 
- (void)play
{
    [_player play];
}

#pragma mark - 暂停
- (void)pause
{
     [_player pause];
}
#pragma mark - 应用退到后台
- (void)appDidEnterBackground
{
    self.didEnterBackground = YES;
    [self pause];
    self.state = HHPlayerStatePause;
   
}


#pragma mark - 应用进入前台
- (void)appDidEnterPlayGround
{
    self.didEnterBackground = NO;
    if (!self.isPauseByUser) {
        self.state                         = HHPlayerStatePlaying;
        self.isPauseByUser                 = NO;
        [self play];
    }
}
#pragma mark - 设置playerLayer的填充模式
- (void)setPlayerLayerGravity:(HHPlayerLayerGravity)playerLayerGravity
{
    _playerLayerGravity = playerLayerGravity;
    // AVLayerVideoGravityResize,           // 非均匀模式。两个维度完全填充至整个视图区域
    // AVLayerVideoGravityResizeAspect,     // 等比例填充，直到一个维度到达区域边界
    // AVLayerVideoGravityResizeAspectFill  // 等比例填充，直到填充满整个视图区域，其中一个维度的部分区域会被裁剪
    switch (playerLayerGravity) {
        case HHPlayerLayerGravityResize:
            self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
            break;
        case HHPlayerLayerGravityResizeAspect:
            self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
            break;
        case HHPlayerLayerGravityResizeAspectFill:
            self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
            break;
        default:
            break;
    }
}
#pragma mark - 播放完了通知
- (void)moviePlayDidEnd:(NSNotification *)notification
{
    self.state = HHPlayerStateStopped;
    if (self.isRepeatPlay) {
        // 没有播放完
        self.playDidEnd    = NO;
        // 重播改为NO
        self.repeatToPlay  = NO;
        [self seekToTime:0 completionHandler:nil];
    }else{
        self.playDidEnd                   = YES;
    }
}
/**
 *  从xx秒开始播放视频跳转
 *
 *  @param dragedSeconds 视频跳转的秒数
 */
- (void)seekToTime:(NSInteger)dragedSeconds completionHandler:(void (^)(BOOL finished))completionHandler
{
    if (self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) {
        // seekTime:completionHandler:不能精确定位
        // 如果需要精确定位，可以使用seekToTime:toleranceBefore:toleranceAfter:completionHandler:
        // 转换成CMTime才能给player来控制播放进度
        CMTime dragedCMTime = CMTimeMake(dragedSeconds, 1);
        [self.player seekToTime:dragedCMTime toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
            // 视频跳转回调
            if (completionHandler) { completionHandler(finished); }
            // 如果点击了暂停按钮
            if (self.isPauseByUser) return ;
            [self play];
            if (!self.playerItem.isPlaybackLikelyToKeepUp && !self.isLocalVideo) {
                self.state = HHPlayerStateBuffering;
            }
            
        }];
    }
}

- (UIButton *)playerStateBut{
    if (!_playerStateBut) {
        _playerStateBut = [UIButton buttonWithType:UIButtonTypeCustom];
        [_playerStateBut setBackgroundImage:HHPlayerImageName(@"hh_player_icon") forState:UIControlStateNormal];
        [self addSubview:_playerStateBut];
        _playerStateBut.hh_frame(CGRectMake(CGRectGetWidth(self.frame)/2 - 30, CGRectGetHeight(self.frame)/2-30, 60, 60));
    }
    return _playerStateBut;
}

- (void)dealloc
{
    // 移除通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
}
@end
